﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Script.Serialization;
using SweetSurvey.Models;
using SweetSurvey.Models.Repositories;
using SweetSurvey.Models.ViewModels;

namespace SweetSurvey.Controllers
{
    public class SurveyController : ControllerBase
    {
        #region Fields
        private IEditorRepository editorRepository;
        private ISurveyRepository surveyRepository;
        private IQuestionRepository questionRepository;
        private IOptionRepository optionRepository;
        private IAnswerRepository answerRepository;
        #endregion

        #region Constructors

        public SurveyController(
            IEditorRepository editorRepository,
            ISurveyRepository surveyRepository,
            IQuestionRepository questionRepository,
            IOptionRepository optionRepository,
            IAnswerRepository answerRepository)
        {
            this.editorRepository = editorRepository;
            this.surveyRepository = surveyRepository;
            this.questionRepository = questionRepository;
            this.optionRepository = optionRepository;
            this.answerRepository = answerRepository;
        }

        #endregion

        //
        // GET: /Survey/

        public ActionResult FillOut(string id)
        {
            ViewBag.SurveyId = id;
            ViewBag.Title = this.surveyRepository.Get(id).Title;
            return View();
        }

        //
        // GET: /Survey/ThankYou

        public ActionResult Submitted(string id)
        {
            ViewBag.Title = this.surveyRepository.Get(id).Title;
            return View(GetSurveyResults(id));
        }

        //
        // GET: /Survey/Report

        public ActionResult Report(string id)
        {
            ViewBag.SurveyTitle = this.surveyRepository.Get(id).Title;
            return View(GetSurveyResults(id));
        }

        private ResultsViewModel GetSurveyResults(string id)
        {
            var questions = this.questionRepository.GetQuestionsBySurveyId(id);
            var results = new ResultsViewModel();
            foreach (var question in questions)
            {
                results.Add(new ResultViewModel(question, this.answerRepository, this.optionRepository));
            }
            return results;
        }

        //
        // GET: /Survey/Details/5

        public ActionResult Details(int id)
        {
            return View();
        }

        //
        // GET: /Survey/Create

        public ActionResult Create()
        {
            return View();
        } 

        //
        // POST: /Survey/Create

        [HttpPost]
        public ActionResult Create(FormCollection collection)
        {
            try
            {
                // TODO: Add insert logic here

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
        
        //
        // GET: /Survey/Edit/5

        public ActionResult Edit(string id)
        {
            ViewBag.SurveyId = id;
            return View();
        }

        [ChildActionOnly]
        public ActionResult EditSurvey(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                ViewBag.QuestionsAjaxUrl = Url.Action("GetSampleQuestions", "Question");
                ViewBag.SurveyTitle = "Sample Survey Title";
            }
            else
            {
                ViewBag.SurveyId = id;
                ViewBag.QuestionsAjaxUrl = Url.Action("GetQuestions", "Question", new { surveyId = id });
                ViewBag.SurveyTitle = this.surveyRepository.Get(id).Title;
            }
            return PartialView();
        }

        //
        // POST: /Survey/Edit/5

        [HttpPost]
        public ActionResult Edit(int id, FormCollection collection)
        {
            try
            {
                // TODO: Add update logic here
 
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        //
        // GET: /Survey/Delete/5
 
        public ActionResult Delete(int id)
        {
            return View();
        }

        //
        // POST: /Survey/Delete/5

        [HttpPost]
        public ActionResult Delete(int id, FormCollection collection)
        {
            try
            {
                // TODO: Add delete logic here
 
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        //
        // POST: /Survey/Publish/...

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Publish(string surveyId, string title, string questions)
        {
            // deserialize questions
            JavaScriptSerializer jss = new JavaScriptSerializer();
            var results = jss.Deserialize<ICollection<QuestionViewModel>>(questions);
            if (results == null || results.Count == 0) { return null; }

            // create the editor
            var editorId = string.Empty;
            if (this.User.Identity.IsAuthenticated)
            {
                var id = this.User.Identity.Name;
                this.editorRepository.CreateIfNotExisted(id);
                editorId = id;
            }
            else
                editorId = this.editorRepository.CreateTemporaryEditor();

            // create the survey
            Survey survey;
            if (string.IsNullOrEmpty(surveyId))
            {
                survey = new Survey() { EditorId = editorId, Title = title, DateCreated = DateTime.Now };
                surveyId = this.surveyRepository.Create(survey);
            }
            else
            {
                // assert owner
                this.surveyRepository.AssertOwner(surveyId, this.User.Identity.Name);
                // update title
                survey = this.surveyRepository.Get(surveyId);
                survey.Title = title;
                surveyRepository.Update(survey);
                // delete old questions
                (new QuestionRepository()).DeleteQuestionsBySurveyId(surveyId);
            }
            
            // create questions
            foreach (var item in results)
            {
                var questionToCreate = new Question();
                item.Apply(ref questionToCreate);
                questionToCreate.SurveyId = surveyId;
                var questionId = this.questionRepository.Create(questionToCreate);
                // create options
                this.optionRepository.CreateOptionsByQuestionId(questionId, item.Options);
            }

            // return redirection url
            return Content(Url.Action("Published", new { id = surveyId }));
        }

        //
        // GET: /Survey/Published/5

        public ActionResult Published(string id)
        {
            ViewBag.SurveyId = id;
            return View();
        }
    }
}
